<template>
  <div class="role-container">
    <el-card class="title" style="height: 60px">
      <span>角色权限管理</span>
    </el-card>
    <el-card :body-style="{ height: 'calc(100% - 200px)' }">
      <template #header>
        <el-button :icon="Plus" type="primary" size="small" @click="addRoleBtn">新增角色</el-button>
      </template>
      <el-table :data="data" stripe size="large" height="100%" highlight-current-row>
        <el-table-column prop="id" label="ID" width="60" />
        <el-table-column prop="roleName" label="角色名称" width="120" />
        <el-table-column prop="roleCode" label="角色代码" width="120" />
        <el-table-column prop="remark" label="备注" show-overflow-tooltip />
        <el-table-column label="状态" width="100">
          <template #default="scope">
            <div style="display: flex; align-items: center">
              <el-tag v-if="scope.row.status === '01'" type="success">启用</el-tag>
              <el-tag v-else type="info">未启用</el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建日期" width="170" />
        <el-table-column prop="createBy" label="创建者" width="140" />
        <el-table-column prop="updateTime" label="更新日期" width="170" />
        <el-table-column prop="updateBy" label="更新者" width="140" />
        <el-table-column fixed="right" label="操作" width="230">
          <template #default="scope">
            <div style="display: flex; align-items: center">
              <el-button
                text
                bg
                size="small"
                :disabled="scope.row.roleCode === 'super'"
                @click="roleMenuBtn(scope.row.id)"
              >
                菜单权限
              </el-button>
              <el-button
                text
                bg
                size="small"
                :disabled="scope.row.roleCode === 'super'"
                @click="editRoleBtn(scope.row)"
              >
                编辑
              </el-button>
              <el-button
                text
                bg
                size="small"
                :disabled="scope.row.roleCode === 'super'"
                @click="deleteRoleBtn(scope.row.id)"
              >
                删除
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <template #footer>
        <div class="footer-content">
          <el-pagination
            background
            size="small"
            layout="total,  prev, pager, next,sizes, jumper"
            :total="total"
            v-model="pageNum"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 30, 50]"
            @size-change="pageSizeChange"
            @current-change="pageNumChange"
          />
        </div>
      </template>
    </el-card>
    <!-- 新增角色抽屉 -->
    <el-drawer title="新增角色" v-model.trim="addRoleDrawer" @closed="addRoleCancel">
      <el-form ref="addRoleRef" :rules="addRoleFormRules" :model="addRoleForm" label-width="100px">
        <el-form-item label="角色名称" prop="roleName">
          <el-input placeholder="角色名称" v-model.trim="addRoleForm.roleName" />
        </el-form-item>
        <el-form-item label="角色代码" prop="roleCode">
          <el-input placeholder="角色代码" v-model.trim="addRoleForm.roleCode" />
        </el-form-item>
        <el-form-item label="是否启用" prop="status">
          <el-switch v-model.trim="addRoleForm.status" active-value="01" inactive-value="00" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input placeholder="备注" type="textarea" v-model.trim="addRoleForm.remark" />
        </el-form-item>
        <el-form-item>
          <el-button plain @click="addRoleCancel">取消</el-button>
          <el-button type="primary" @click="addRoleSubmit(addRoleRef)">提交</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
    <!-- 编辑角色抽屉 -->
    <el-drawer title="编辑角色" v-model="editRoleDrawer" @closed="editRoleCancel">
      <el-form
        ref="editRoleRef"
        :rules="editRoleFormRules"
        :model="editRoleForm"
        label-width="100px"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input placeholder="角色名称" v-model.trim="editRoleForm.roleName" />
        </el-form-item>
        <el-form-item label="角色代码" prop="roleCode">
          <el-input placeholder="角色代码" v-model.trim="editRoleForm.roleCode" />
        </el-form-item>
        <el-form-item label="是否启用" prop="status">
          <el-switch v-model.trim="editRoleForm.status" active-value="01" inactive-value="00" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input placeholder="备注" type="textarea" v-model.trim="editRoleForm.remark" />
        </el-form-item>
        <el-form-item>
          <el-button plain @click="editRoleCancel">取消</el-button>
          <el-button type="primary" @click="editRoleSubmit(editRoleRef)">提交</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
    <!-- 角色菜单编辑 -->
    <el-drawer title="角色菜单" v-model.trim="roleMenuDrawer">
      <el-button type="primary" style="margin-bottom: 20px" @click="saveRelation">保存</el-button>
      <el-tree-v2
        ref="permTreeRef"
        show-checkbox
        :data="treeData"
        :props="{ value: 'id', label: 'menuName', children: 'children' }"
      />
    </el-drawer>
  </div>
</template>

<script lang="ts" setup>
import { Plus } from '@element-plus/icons-vue'
import { ElTreeV2 as Tree2 } from 'element-plus'
import {
  getRoleList,
  addRole,
  updateRole,
  deleteRole,
  getRelation,
  getMenuConcise,
  updateRelation
} from '@/api/system/role'

/**
 * 分页参数
 */
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const data = ref<Role[]>()

function toGetList() {
  getRoleList({
    pageNum: pageNum.value,
    pageSize: pageSize.value
  }).then((res) => {
    if (res.code === 200) {
      data.value = res.data?.list
      total.value = res.data?.total!
    }
  })
}

onMounted(() => {
  toGetList()
  getMenuConcise().then((res) => {
    if (res.code === 200) {
      treeData.value = res.data
    }
  })
})

function pageSizeChange() {
  toGetList()
}

function pageNumChange() {
  toGetList()
}

/**
 * 增加角色
 */
const addRoleFormRules = reactive({
  roleName: { required: true, message: '请填写角色名称' },
  roleCode: { required: true, message: '请填写角色代码' },
  status: { required: true, message: '' }
})
const addRoleDrawer = ref(false)
const addRoleRef = ref()
const addRoleForm = ref<Role>({
  id: 0,
  roleName: '',
  roleCode: '',
  remark: '',
  createTime: '',
  createBy: 1,
  updateTime: '',
  updateBy: 1,
  status: '01'
})
// 新增角色按钮
function addRoleBtn() {
  addRoleDrawer.value = true
}
// 取消新增角色
function addRoleCancel() {
  addRoleDrawer.value = false
  addRoleForm.value.id = 0
  addRoleForm.value.roleName = ''
  addRoleForm.value.roleCode = ''
  addRoleForm.value.status = '01'
  addRoleForm.value.remark = ''
}
// 新增角色提交
async function addRoleSubmit(formR: FormInstance) {
  if (!formR) return
  await formR.validate((vaild) => {
    if (vaild) {
      addRole(addRoleForm.value).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '添加成功',
            type: 'success'
          })
          addRoleCancel()
          toGetList()
        }
      })
    }
  })
}
/**
 * 编辑角色
 */
const editRoleFormRules = reactive({
  roleName: { required: true, message: '请填写角色名称' },
  roleCode: { required: true, message: '请填写角色代码' },
  status: { required: true, message: '' }
})
const editRoleDrawer = ref(false)
const editRoleRef = ref()
const editRoleForm = ref<Role>({
  id: 0,
  roleName: '',
  roleCode: '',
  remark: '',
  createTime: '',
  createBy: 1,
  updateTime: '',
  updateBy: 1,
  status: '01'
})
// 编辑按钮
function editRoleBtn(role: Role) {
  editRoleForm.value.id = role.id
  editRoleForm.value.roleName = role.roleName
  editRoleForm.value.roleCode = role.roleCode
  editRoleForm.value.status = role.status
  editRoleForm.value.remark = role.remark
  editRoleDrawer.value = true
}
// 编辑取消
function editRoleCancel() {
  editRoleDrawer.value = false
  editRoleForm.value.id = 0
  editRoleForm.value.roleName = ''
  editRoleForm.value.roleCode = ''
  editRoleForm.value.status = '01'
  editRoleForm.value.remark = ''
}
// 编辑提交
async function editRoleSubmit(formR: FormInstance) {
  if (!formR) return
  await formR.validate((vaild: boolean) => {
    if (vaild) {
      updateRole(editRoleForm.value).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '更新成功',
            type: 'success'
          })
          editRoleCancel()
          toGetList()
        }
      })
    }
  })
}
/**
 * 删除角色
 */
function deleteRoleBtn(id: number) {
  ElMessageBox.confirm('确认删除所选择的角色吗?', '删除角色', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      deleteRole(id).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '删除成功',
            type: 'success'
          })
          toGetList()
        }
      })
    })
    .catch(() => {})
}
/**
 * 菜单权限关联
 */
const roleMenuDrawer = ref(false)
const permTreeRef = ref<InstanceType<typeof Tree2>>()
const treeData = ref<Menu[]>()
const editRoleId = ref(0)
// 菜单编辑按钮
function roleMenuBtn(id: number) {
  roleMenuDrawer.value = true
  editRoleId.value = id
  getRelation(id).then((res) => {
    if (res.code === 200) {
      permTreeRef.value?.setCheckedKeys(res.data!)
    }
  })
}
// 关联保存按钮
function saveRelation() {
  let menuIds = permTreeRef.value?.getCheckedKeys(false) as number[]
  updateRelation(editRoleId.value, menuIds).then((res) => {
    if (res.code === 200) {
      ElMessage({
        message: '保存成功',
        type: 'success'
      })
      roleMenuDrawer.value = false
    }
  })
}
</script>

<style lang="scss" scoped>
.role-container {
  height: 100%;
  width: 100%;
  .title {
    margin-bottom: 13px;
    span {
      font-size: 16px;
      font-weight: 500;
    }
  }
  .el-card {
    height: calc(100% - 77px);
  }
  :deep(.el-card__footer) {
    border: none;
  }
  .footer-content {
    display: flex;
    align-items: center;
    justify-content: end;
  }
}
</style>
